﻿using System;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Media.Imaging;
using Microsoft.Phone.Controls;

namespace SurfaceInteraction.UI.WP7
{
    public partial class RemoteDesktopPage : PhoneApplicationPage
    {
        private Timer idleTimer = null;
        private Timer downloadTimer = null;
        public RemoteDesktopPage()
        {
            InitializeComponent();
            ResetIdleTimer();
            this.Loaded += new RoutedEventHandler(RemoteDesktopPage_Loaded);
        }

        void RemoteDesktopPage_Loaded(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
        }

        

        #region idleTimerCallback
        private void Idle_Timer_TimerCallback(object sender)
        {
            DisableIdleTimer();

            try
            {
                if (Configuration.Id == 0)
                {
                    this.Dispatcher.BeginInvoke(() => { MessageBox.Show("You must set an id in the Settings page before use the application", "Warning", MessageBoxButton.OK); });
                }
                else
                {
                    //RDServiceReference.RemoteDesktopClient cli = new RDServiceReference.RemoteDesktopClient("RemoteDesktopServiceEP");
                    RDServiceReference.RemoteDesktopClient cli = new RDServiceReference.RemoteDesktopClient(Configuration.REMOTE_DESKTOP_SERVICE_EP, Configuration.RemoteDesktop_ServiceURL);
                    cli.GetFrameAsync(Configuration.Id);
                    cli.GetFrameCompleted += new EventHandler<RDServiceReference.GetFrameCompletedEventArgs>(cli_GetFrameCompleted);
                }
            }
            catch (Exception ex)
            {
                // handle the exception    
            }
            
        }
        #endregion

        #region IdleTimer methods
        private void ResetIdleTimer()
        {
            if (idleTimer != null)
                idleTimer.Change(new TimeSpan(0, 0, 0, 0, Configuration.IdleTimeRemoteDesktopInMilliSeconds), new TimeSpan(0, 0, 0, 0, -1));
            else
                idleTimer = new Timer(new TimerCallback(Idle_Timer_TimerCallback), null, new TimeSpan(0, 0, 0, 0, Configuration.IdleTimeRemoteDesktopInMilliSeconds), new TimeSpan(0, 0, 0, 0, -1));
        }

        private void DisableIdleTimer()
        {
            if (idleTimer != null)
            {
                idleTimer.Change(Timeout.Infinite, Timeout.Infinite);
                idleTimer.Dispose();
                idleTimer = null;
            }
        }
        #endregion

        #region async RemoteDesktopClient event
        void cli_GetFrameCompleted(object sender, RDServiceReference.GetFrameCompletedEventArgs e)
        {
            try
            {
                RDServiceReference.RemoteDesktopFrame rd = e.Result as RDServiceReference.RemoteDesktopFrame;

                if (rd != null && rd.Frame != null)
                {
                    BitmapImage source = null;
                    this.Dispatcher.BeginInvoke(() => source = new BitmapImage());

                    MemoryStream stream = new MemoryStream(rd.Frame);
                    this.Dispatcher.BeginInvoke(() => source.SetSource(stream));


                    this.Dispatcher.BeginInvoke(() => im.Source = source);
                    this.Dispatcher.BeginInvoke(() => PageTitle.Text = "");
                }
            }
            catch (Exception ex)
            {
                this.Dispatcher.BeginInvoke(() => PageTitle.Text = "xConnecting");
            }

            ResetIdleTimer();
        }
        #endregion

        #region downloadTimerCallback
        private void Download_Timer_TimerCallback(object sender)
        {
            DisableDownloadTimer();

            try
            {
                FEReference.FileExchangeClient cli = new FEReference.FileExchangeClient("FileExchangeEP");
                cli.DownloadAsync(id);
                cli.DownloadCompleted += new EventHandler<FEReference.DownloadCompletedEventArgs>(cli_DownloadCompleted);              
            }
            catch (Exception ex)
            {
                // handle the exception    
            }

        }
        #endregion

        #region async Download event
        void cli_DownloadCompleted(object sender, FEReference.DownloadCompletedEventArgs e)
        {
            try
            {
                if (e.Result != null)
                {
                    //BitmapImage source = null;
                    this.Dispatcher.BeginInvoke(() => _image = new BitmapImage());

                    MemoryStream stream = new MemoryStream(e.Result);
                    this.Dispatcher.BeginInvoke(() => _image.SetSource(stream));
                    
                    this.Dispatcher.BeginInvoke(() => NavigationService.Navigate(new Uri("/ContentList.xaml", UriKind.Relative)));
                }
                else
                {
                    ResetDownloadTimer();
                }
            }
            catch (Exception ex)
            { 
            
            }

            
        }
        #endregion

        #region downloadTimer methods
        private void ResetDownloadTimer()
        {
            if (downloadTimer != null)
                downloadTimer.Change(new TimeSpan(0, 0, 0, 0, Configuration.DownloadTimerInMilliSeconds), new TimeSpan(0, 0, 0, 0, -1));
            else
                downloadTimer = new Timer(new TimerCallback(Download_Timer_TimerCallback), null, new TimeSpan(0, 0, 0, 0, Configuration.DownloadTimerInMilliSeconds), new TimeSpan(0, 0, 0, 0, -1));
        }

        private void DisableDownloadTimer()
        {
            if (downloadTimer != null)
            {
                downloadTimer.Change(Timeout.Infinite, Timeout.Infinite);
                downloadTimer.Dispose();
                downloadTimer = null;
            }
        }
        #endregion
        Guid id = new Guid();
        #region page events
        private void OnHold(object sender, GestureEventArgs e)
        {
            FEReference.FileExchangeClient cli = new FEReference.FileExchangeClient("FileExchangeEP");
            id = Guid.NewGuid();
            cli.DownloadRequestAsync(Configuration.Id, id);
            ResetDownloadTimer();
        }
        #endregion

        #region settings

        void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            if (e.Content is RemoteDesktopPage)
            {
                DisableIdleTimer();
                ResetIdleTimer();
            }
        }
        #endregion


        private BitmapImage _image;

        public BitmapImage Image
        {
            get { return _image; }
            set
            {
                _image = value;
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/SettingsPage.xaml", UriKind.Relative));
        }
    }
}